package com.jly.Util;

import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Set;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * @author jiangjie 签名工具
 */
public class SignUtil {
	public static Logger logger = Logger.getLogger(SignUtil.class);

	public final static String key = "c05746d694d5e717d344e5f3593b2d7e";// API密钥

	/**
	 * 生成带有MD5签名的sign的 json格式字符串
	 *
	 * @param data
	 *            json类型数据
	 * @return 含有sign字段的json字符串
	 */
	public static String generateSignedJson(JSONObject data) {
		String sign = generateSignature(data);
		data.put("sign", sign);
		return data.toJSONString();
	}

	/**
	 * 判断签名是否正确
	 *
	 * @param jsonStr
	 *        json格式数据
	 * @return 签名是否正确
	 * @throws Exception
	 */
	public static boolean isSignatureValid(String jsonStr) {
		JSONObject data = JSON.parseObject(jsonStr);
		if (!data.containsKey("sign")) {// 不包含签名字符串,直接返回签名不正确
			return false;
		}
		String sign = data.get("sign").toString();
		return generateSignature(data).equals(sign);
	}

	/**
	 * MD5签名方式生成签名
	 *
	 * @param data
	 *            待签名数据
	 * @return 签名
	 */
	public static String generateSignature(JSONObject data) {
		Set<String> keySet = data.keySet();
		String[] keyArray = keySet.toArray(new String[keySet.size()]);
		Arrays.sort(keyArray);// 字符串排序
		StringBuilder sb = new StringBuilder();
		for (String k : keyArray) {
			if (k.equals("sign")) {// 去掉sign的键
				continue;
			}
			if (data.get(k).toString().trim().length() > 0) // 参数值为空，则不参与签名
				sb.append(k).append("=").append(data.get(k).toString().trim()).append("&");
		}
		sb.append("key=").append(key);
		return MD5(sb.toString());
	}

	/**
	 * 生成 MD5
	 *
	 * @param data
	 *            待处理数据
	 * @return MD5结果
	 */
	public static String MD5(String str) {
		logger.info("签名字符串:" + str);
		StringBuffer md5StrBuff = new StringBuffer();
		MessageDigest messageDigest = null;
		try {
			messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			messageDigest.update(str.getBytes("UTF-8"));
			byte[] byteArray = messageDigest.digest();
			for (int i = 0; i < byteArray.length; i++) {
				if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
					md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
				else
					md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
			}
			logger.info("签名结果:" + md5StrBuff.toString());
			return md5StrBuff.toString();
		} catch (Exception e) {
			e.printStackTrace();
			logger.info("生成 MD5异常");
		}
		return null;
	}

	public static void main(String[] args) {
	}

}
